use std::{fs, io, path::Path};

use colored::Colorize;
use rig::{completion::ToolDefinition, tool::Tool};
use serde::{Deserialize, Serialize};
use serde_json::json;

#[derive(Deserialize)]
pub struct OperationArgs {
    path: String,
}

#[derive(Debug, thiserror::Error)]
#[error("Math error")]
pub struct CatError;

#[derive(Deserialize, Serialize)]
pub struct CatCmd {
    pub project_path: String,
}

impl Tool for CatCmd {
    const NAME: &'static str = "cat";

    type Error = CatError;
    type Args = OperationArgs;
    type Output = String;

    async fn definition(&self, _prompt: String) -> ToolDefinition {
        ToolDefinition {
            name: "cat".to_string(),
            description: "给定文件地址，输出文件内容".to_string(),
            parameters: json!({
                "type": "object",
                "properties": {
                    "path": {
                        "type": "string",
                        "description": "the path needed to outut"
                    }
                }
            }),
        }
    }

    async fn call(&self, args: Self::Args) -> Result<Self::Output, Self::Error> {
        println!("{}", format!("cat {}", args.path).red());
        let res = cat(&self.project_path, args.path);
        Ok(res)
    }
}

fn cat(pwd: &String, path: String) -> String {
    let base_path = Path::new(pwd);
    let real_path_op = base_path
        .join(&path)
        .canonicalize()
        .map(|i| i.display().to_string());

    if let Ok(real_path) = real_path_op {
        // 文件信息
        let metadata_Res = fs::metadata(&real_path);
        if let Ok(metadata) = metadata_Res {
            if metadata.len() > 100000 {
                return format!("文件太大，无法显示 {}", real_path);
            }
        }
    
        let content = fs::read_to_string(&real_path);
        if let Ok(content) = content {
            return format!("文件内容{}\n{}", path, content);
        } else {
            return format!("文件 {} 不存在", real_path);
        }
    } else {
        return format!("文件 {} 不存在", path);
    }

}
